package ripple.common;

import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.net.InetSocketAddress;
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;

import ripple.common.entity.NodeMetadata;

public class DebugTool {

    public static int flag = 0;

    public static void prepareDir(File file) {
        if (!file.isDirectory()) {
            return;
        }

        if (!file.exists()) {
            file.mkdirs();
        } else {
            DebugTool.cleanDir(file);
        }

    }

    public static void cleanDir(File file) {
        if (file.listFiles() == null) {
            file.delete();
            return;
        }
        for (File temp : file.listFiles()) {
            if (file.isDirectory()) {
                DebugTool.cleanDir(temp);
            }
            temp.delete();
        }
    }

    public static void write(File file, String content) {
        try {
            FileWriter writer = new FileWriter(file, true);
//            writer.write("");//清空原文件内容
            writer.write(content + "\n");
            writer.flush();
            writer.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public static synchronized void debugInfo(String content) {
        write(new File("debug/debug.txt"), content);
    }

    private static String storageLocation = "data";

    public static void write(String content) {
        write("debugInfo", content);
    }

    public static void write(String filename, String content) {
        String filepath = storageLocation + "/" + filename + ".txt";
//        File file = new File(filepath);
        try {
            FileWriter writer = new FileWriter(filepath, true);
//            writer.write("");//清空原文件内容
            writer.write(content + "\n");
            writer.flush();
            writer.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public static String buildInfo(Class className, String methodName, String info) {
        return "[" + className.toString() + "] Method: " + methodName + " Info: " + info;
    }

    public static void cleanDirectory(File file) {
        File[] list = file.listFiles();  //无法做到list多层文件夹数据
        if (list != null) {
            for (File temp : list) {     //先去递归删除子文件夹及子文件
                deleteDirectoryLegacyIO(temp);   //注意这里是递归调用
            }
        }
    }

    public static void deleteDirectoryLegacyIO(File file) {

        cleanDirectory(file);

        if (file.delete()) {     //再删除自己本身的文件夹
            System.out.printf("删除成功 : %s%n", file);
        } else {
            System.err.printf("删除失败 : %s%n", file);
        }
    }

    public static synchronized void addNodeList(List<NodeMetadata> nodeList) {

        try {
            FileWriter writer = new FileWriter("debug/nodelist.txt", true);
//            writer.write("");//清空原文件内容
            writer.write(NodeMetadata.ListToString(nodeList) + "\n");
            writer.flush();
            writer.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public static synchronized List<NodeMetadata> getNodeList() {

        List<NodeMetadata> nodeList = new ArrayList<>();
        try (Scanner sc = new Scanner(new FileReader("debug/nodelist.txt"))) {
            while (sc.hasNextLine()) {
                nodeList.addAll(NodeMetadata.ListFromString(sc.nextLine()));
                // String line = sc.nextLine();
                // System.out.println(line);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        // for (NodeMetadata nodeMetadata : nodeList) {
        //     System.out.println("[Node " + nodeMetadata.getId() + "] "
        //             + "Address = " + nodeMetadata.getAddress()
        //             + ", port = " + nodeMetadata.getPort());
        // }
        return nodeList;
    }

    public static int findIdByAddress(InetSocketAddress address) {
        List<NodeMetadata> nodeList = getNodeList();
        for (NodeMetadata node : nodeList) {
            if (node.getAddress().equals(address.getHostString())
                    && node.getPort() == address.getPort()) {
                return node.getId();
            }
        }
        return -1;

    }

    public static synchronized void addClientNodeList(List<NodeMetadata> nodeList) {

        try {
            FileWriter writer = new FileWriter("debug/clientNodelist.txt", true);
//            writer.write("");//清空原文件内容
            writer.write(NodeMetadata.ListToString(nodeList) + "\n");
            writer.flush();
            writer.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public static synchronized List<NodeMetadata> getClientNodeList() {

        List<NodeMetadata> nodeList = new ArrayList<>();
        try (Scanner sc = new Scanner(new FileReader("debug/clientNodelist.txt"))) {
            while (sc.hasNextLine()) {
                nodeList.addAll(NodeMetadata.ListFromString(sc.nextLine()));
                // String line = sc.nextLine();
                // System.out.println(line);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        for (NodeMetadata nodeMetadata : nodeList) {
            System.out.println("[Client Node " + nodeMetadata.getId() + "] "
                    + "Address = " + nodeMetadata.getAddress()
                    + ", port = " + nodeMetadata.getPort());
        }
        return nodeList;
    }

    public static int findClientIdByAddress(InetSocketAddress address) {
        List<NodeMetadata> nodeList = getClientNodeList();
        for (NodeMetadata node : nodeList) {
            if (node.getAddress().equals(address.getHostString())
                    && node.getPort() == address.getPort()) {
                return node.getId();
            }
        }
        return -1;

    }

}
